// 可以用系统提供的守护进程函数
// 也可以自己写
// 调用函数时setsid()
#pragma once
#include <iostream>
#include <cassert>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define DEV "/dev/null"
void daemonSelf(const char* curPath = nullptr)
{
    // 守护进程化的流程
    // 1.让调用进程忽略异常的信号
    signal(SIGPIPE, SIG_IGN);
    // 2.如何让自己不是组长，setsid
    if (fork() > 0)
        exit(0); // 将父进程退出，子进程跟父进程的进程地址，页表一样
    // 由子进程来当组长
    int n = setsid();
    assert(n!=-1);
    // 3. 守护进程是脱离终端的 关闭或者重定向以前进程默认打开的文件,把默认打开的012文件描述符重定向到 /dev/null
    int fp = open(DEV,O_RDWR);
    if(fp!=-1)
    {
        dup2(fp,0);
        dup2(fp,1);
        dup2(fp,2);
        close(fp);
    }
    else
    {
        close(0);
        close(1);
        close(2);

    }
    // 4.可选：进程执行路径发生改变,主要是进程自带属性cwd 当前工作路径
    // cwd 属性可以在/proc/pid 文件夹中查看
    if(curPath) chdir(curPath);
}